 BEGIN {
     Number = "^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)([eE][+-]?[0-9]+)?$"
     Q = "\"" 
     Pi = 3.1415926535
     E  = 2.7182818284 
     Inf= 10^32
 }
 function isNum(x,d) { return ((x=="") ? d : x+0) }
 function here(x) { return ENVIRON["Here"] "/" x }
 function data(x) { return ENVIRON["Here"] "/data/" x }
 function abs(x)  { return x < 0 ? -1*x : x }
 function trim(x) {
   gsub(/^[ \t\r\n]*/,"",x)
   gsub( /[ \t\r\n]*$/,"",x)
   return x
 }
 function valdesc(a,b,c,d) { return b["val"] - d["val"] }
 function valasc( a,b,c,d) { return d["val"] - b["val"] }

 function onum(l,prefix) { o(l,prefix,"@ind_num_asc") }
 function ostr(l,prefix) { o(l,prefix,"@ind_str_asc") }

 function o(l,prefix,order,   indent,   old,i) {
     if (!order)
         for(i in l) { 
             order = i ~ Number ? "@ind_num_asc" :"@ind_num_asc"
             break
         }
    old = PROCINFO["sorted_in"] 
    PROCINFO["sorted_in"]= order
    for(i in l) 
        if (isarray(l[i])) {
            print indent prefix "[" i "]"
            o(l[i],"",order, indent "|   ")
         } else
             print indent prefix "["i"] = (" l[i] ")"
    PROCINFO["sorted_in"]  = old 
 }
 
 function dots(n) {
   if (n=="") n= ++ _Dots
   if ( ! (n % 3125))  say("!")
    else if ( ! (n % 625))  say("*")
    else if ( ! (n % 125))  say("+")
    else if ( ! (n % 25))  say(".")
 }
 function by(new,   old) {
    if (new=="")
      return by("@ind_num_asc")
    old = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = new
    return old
 }
 function say(x) {
   printf x > "/dev/stderr"
 }
 function keys (a,k, i) {
   for(i in a) k[i]
 }
 function copy(x,y,    i) {
   array(y)
   for(i in x) y[i] = x[i]
   }
 function concat(x,y,z, i,n) {
    for(i in x) z[++n] = x[i]
    for(i in y) z[++n] = y[i]
 }
 function overlap(x,y,z,   i,n) {
   array(z)
   for(i in x)
     if(i in y)
       n += (z[i] = 1)
   return n
   }
 function array(x) {
   split("",x,"")
 }
 function mediank(key,l,   i,tmp) {
   for(i in l)  tmp[i] = l[key]
   return median(tmp)
 }
 function median(l,   n,s,m) {
   n = asort(l,s)
   m = int(n/2)
   return n % 2 ? (s[m] + s[m+1]) / 2 : s[m]
 }
 function middle50k(key,l,   i,tmp) {
   for(i in l) tmp[i] = l[key]
   return middle50(tmp)
 }
 function middle50(l,    n,s,lo,hi) {
   n = asort(l,s);
   lo = int(n*0.25 + 0.5)
   hi = int(n*0.75 + 0.5)
   return s[hi] - s[lo]
 }
 function some(l,p,ins,outs,   i) {
   for(i in l)
     rand() > p ? ins[i] : outs[i]
 }
 function any(l) {
     return l[int(rand()*length(l)) + 1]
 }
 function sd(n,sumX,sumSq,  tmp) {
   return sqrt((sumSq-((sumX*sumX)/n))/(n-1))
 }
 function mean(l) {
   return sum(l)/length(l)
 }
 function l2sd(l,    i,n,s,sq) {
   for(i in l) {
     n++
     s += l[i]
     sq += l[i]*l[i]
   }
   return sd(n,s,sq)
 }
 function sum(l,   i,n) {
   for(i in l) n += l[i]
   return n
 }
 function normal(mean, std){  
   return mean + box_muller()*std;
 }
 function box_muller(   w,n,x1,x2) {
   w=1;  
   while (w >= 1) { 
     x1= 2.0 * rand() - 1;  
     x2= 2.0 * rand() - 1; 
     w = x1*x1 + x2*x2
   };
   w = sqrt((-2.0 * log(w))/w);
   return x1 * w;
 }
 function effectSize(mean1,mean2,sd) {
   return abs(mean1 - mean2)/sd
 }
 function push(x,l,   i) {
   i = length(l) + 1
   l[i] = x
   return x
 } 
